import React, { useState, useCallback, useEffect, useRef } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import {
  ReactFlow,
  Node,
  Edge,
  Background,
  Controls,
  MiniMap,
  useNodesState,
  useEdgesState,
  addEdge,
  Connection,
  NodeTypes,
  Handle,
  Position,
  MarkerType,
  NodeChange,
  EdgeChange,
  useReactFlow,
  ReactFlowProvider,
} from '@xyflow/react'
import '@xyflow/react/dist/style.css'
import {
  Box,
  Typography,
  Button,
  TextField,
  IconButton,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  List,
  ListItem,
  ListItemButton,
  ListItemText,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Drawer,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  FormHelperText,
  Snackbar,
  Alert,
  Paper,
  CircularProgress,
  Table,
  TableHead,
  TableBody,
  TableCell,
  TableRow,
  TableContainer,
  TablePagination,
} from '@mui/material'
import {
  ArrowBack as ArrowBackIcon,
  Save as SaveIcon,
  ExpandMore as ExpandMoreIcon,
  PlayArrow as PlayArrowIcon,
  Visibility as VisibilityIcon,
  PlayCircle as PlayCircleIcon,
  UploadFile,
  Delete as DeleteIcon,
} from '@mui/icons-material'
import { workflows } from '../services/api'
import * as XLSX from 'xlsx'
import DataTableDialog from '../components/dialogs/DataTableDialog'

// 添加全局样式
import './WorkflowEditor.css'

// 定义节点类型
import { nodeTypeMapping, CustomNode, NodeData, NodeParams } from '../components/nodes'

// 导入节点面板和属性面板组件
import NodePanel from '../components/panels/NodePanel'
import PropertiesPanel from '../components/panels/PropertiesPanel'

// 边属性面板
interface EdgePropertiesPanelProps {
  edge: Edge
  onDelete: (edgeId: string) => void
}

const EdgePropertiesPanel = ({ edge, onDelete }: EdgePropertiesPanelProps) => {
  return (
    <Box>
      <Typography variant="h6" gutterBottom>
        边属性
      </Typography>
      <Box sx={{ mb: 2 }}>
        <Typography variant="subtitle1">
          源节点: {edge.source}
        </Typography>
        <Typography variant="subtitle1">
          目标节点: {edge.target}
        </Typography>
      </Box>
      <Box sx={{ mb: 2 }}>
        <Button
          variant="outlined"
          color="error"
          onClick={() => onDelete(edge.id)}
        >
          删除边
        </Button>
      </Box>
    </Box>
  )
}

// 预览面板
interface PreviewPanelProps {
  nodes: CustomNode[]
  edges: Edge[]
}

const PreviewPanel = ({ nodes, edges }: PreviewPanelProps) => {
  return (
    <Box>
      <Typography variant="h6" gutterBottom>
        工作流预览
      </Typography>
      <Box sx={{ mb: 2 }}>
        <Typography variant="subtitle1">节点数量: {nodes.length}</Typography>
        <Typography variant="subtitle1">边数量: {edges.length}</Typography>
      </Box>
      <Box>
        <Typography variant="subtitle1">节点列表:</Typography>
        <List>
          {nodes.map((node) => (
            <ListItem key={node.id}>
              <ListItemText
                primary={node.data.label}
                secondary={`类型: ${node.data.type}`}
              />
            </ListItem>
          ))}
        </List>
      </Box>
    </Box>
  )
}

const WorkflowEditor = () => {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const [nodes, setNodes, onNodesChange] = useNodesState<CustomNode>([])
  const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>([])
  const [selectedNode, setSelectedNode] = useState<CustomNode | null>(null)
  const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null)
  const [isDrawerOpen, setIsDrawerOpen] = useState(false)
  const [isPreviewOpen, setIsPreviewOpen] = useState(false)
  const [isExecuteDialogOpen, setIsExecuteDialogOpen] = useState(false)
  const [isLoading, setIsLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [success, setSuccess] = useState<string | null>(null)
  const [workflowName, setWorkflowName] = useState('')
  const [workflowDescription, setWorkflowDescription] = useState('')
  const [isNewWorkflow, setIsNewWorkflow] = useState(false)
  
  // 添加结构化视图相关状态
  const [isDataTableOpen, setIsDataTableOpen] = useState(false)
  const [tableData, setTableData] = useState<any[] | null>(null)
  const [tableColumns, setTableColumns] = useState<string[] | null>(null)
  const [tableTitle, setTableTitle] = useState('数据预览')
  const [tablePageSize, setTablePageSize] = useState(10)
  
  // 使用ref存储函数引用，避免循环依赖
  const nodeExecuteRef = useRef<(nodeId: string) => Promise<any>>(async () => ({}));
  
  // 使用 ReactFlow 实例
  const reactFlowInstance = useReactFlow()

  // 获取上游数据的函数
  const getUpstreamData = useCallback(() => {
    if (!selectedNode) {
      console.log('没有选中的节点');
      return { columns: [], data: [] };
    }
    
    console.log('当前选中的节点:', selectedNode);
    
    // 找到指向当前节点的边
    const incomingEdges = edges.filter(edge => edge.target === selectedNode.id);
    if (incomingEdges.length === 0) {
      console.log('没有找到指向当前节点的边');
      return { columns: [], data: [] };
    }
    
    // 获取上游节点
    const sourceNodeId = incomingEdges[0].source;
    const sourceNode = nodes.find(node => node.id === sourceNodeId);
    
    if (!sourceNode) {
      console.log('找不到上游节点');
      return { columns: [], data: [] };
    }

    console.log('上游节点数据:', sourceNode.data);
    
    // 从上游节点的执行结果中获取列信息和数据
    let columns: string[] = [];
    let data: any[] = [];
    
    // 首先尝试从lastExecutionResult中获取列信息和数据
    if (sourceNode.data.lastExecutionResult) {
      console.log('上游节点执行结果:', sourceNode.data.lastExecutionResult);
      
      if ('columns' in sourceNode.data.lastExecutionResult) {
        columns = sourceNode.data.lastExecutionResult.columns as string[];
        console.log('从 lastExecutionResult.columns 获取到列:', columns);
      }
      if ('data' in sourceNode.data.lastExecutionResult) {
        data = sourceNode.data.lastExecutionResult.data as any[];
        console.log('从 lastExecutionResult.data 获取到数据:', data);
      }
    }
    // 如果还是没有找到列信息，尝试从params中获取
    else if (sourceNode.data.params?.columns) {
      if (typeof sourceNode.data.params.columns === 'string') {
        columns = sourceNode.data.params.columns.split(',').map(col => col.trim());
      } else if (Array.isArray(sourceNode.data.params.columns)) {
        columns = sourceNode.data.params.columns;
      }
      console.log('从 params.columns 获取到列:', columns);
    }

    console.log('最终获取到的列信息和数据:', { columns, data });
    return { columns, data };
  }, [selectedNode, edges, nodes]);

  // 获取前序节点的函数
  const getPredecessorNodes = useCallback((nodeId: string): string[] => {
    const result: string[] = []
    const visited = new Set<string>()

    const dfs = (currentNodeId: string) => {
      if (visited.has(currentNodeId)) return
      visited.add(currentNodeId)
      result.push(currentNodeId)

      // 找到所有指向当前节点的边
      const incomingEdges = edges.filter(edge => edge.target === currentNodeId)
      incomingEdges.forEach(edge => {
        dfs(edge.source)
      })
    }

    dfs(nodeId)
    return result
  }, [edges]);

  // 处理节点执行
  const handleNodeExecute = useCallback(async (nodeId: string) => {
    // 找到要执行的节点
    const nodeToExecute = nodes.find(n => n.id === nodeId);
    if (nodeToExecute) {
      console.log("执行节点:", nodeId, nodeToExecute.data);
      
      // 检查是否是结构化视图节点
      if (nodeToExecute.data.type === 'structured_view') {
        await handleStructuredViewNode(nodeId);
        return;
      }
      
      // 如果是模型评估节点，先执行上游的机器学习模型节点
      if (nodeToExecute.data.type === 'model_evaluation') {
        console.log("检测到模型评估节点，查找上游机器学习模型节点");
        const incomingEdges = edges.filter(edge => edge.target === nodeId);
        if (incomingEdges.length > 0) {
          const sourceNodeId = incomingEdges[0].source;
          const sourceNode = nodes.find(n => n.id === sourceNodeId);
          
          if (sourceNode) {
            console.log(`找到上游节点 ${sourceNodeId}，类型: ${sourceNode.data.type}`);
            if (['logistic_regression', 'random_forest', 'svm'].includes(sourceNode.data.type)) {
              console.log(`先执行上游机器学习模型节点 ${sourceNodeId}`);
              try {
                const result = await nodeExecuteRef.current(sourceNodeId);
                console.log(`上游节点 ${sourceNodeId} 执行结果:`, result);
              } catch (error) {
                console.error(`执行上游节点 ${sourceNodeId} 失败:`, error);
              }
            }
          }
        }
      }
      
      // 检查文件路径
      const filePath = nodeToExecute.data.params?.filePath;
      if (nodeToExecute.data.type && 
          (nodeToExecute.data.type === 'csv_reader' || nodeToExecute.data.type === 'excel_reader') && 
          !filePath) {
        throw new Error('文件路径不存在，请先上传文件');
      }
    }
    
    // 获取当前节点和依赖节点列表
    let nodeIds = getPredecessorNodes(nodeId);
    console.log("原始节点执行顺序:", nodeIds);
    
    try {
      // 准备要发送的节点数据
      const nodesMap: Record<string, any> = {};
      
      // 处理当前要执行的节点
      for (const id of nodeIds) {
        const node = nodes.find(n => n.id === id);
        if (node) {
          nodesMap[id] = {
            id: node.id,
            data: {
              ...node.data,
              ...(node.data.lastExecutionResult ? { lastExecutionResult: node.data.lastExecutionResult } : {}),
              params: {
                ...node.data.params,
                // 确保将 File 对象从参数中移除，因为它不能被序列化
                file: undefined
              }
            }
          };
        }
      }
      
      // 关键修改：找出并添加所有上游节点
      if (nodeToExecute && 
          ['logistic_regression', 'random_forest', 'svm', 'model_evaluation', 'one_hot_encoding', 'data_standardization', 'data_cleaning', 'outlier_detection'].includes(nodeToExecute.data.type)) {
        // 模型评估节点特殊处理，需要详细记录
        if (nodeToExecute.data.type === 'model_evaluation') {
          console.log(`开始处理模型评估节点 ${nodeId}，查找上游模型节点...`);
        } else if (['one_hot_encoding', 'data_standardization', 'data_cleaning', 'outlier_detection'].includes(nodeToExecute.data.type)) {
          console.log(`开始处理数据处理节点 ${nodeId}，查找上游数据节点...`);
        }
        
        // 找到所有指向当前节点的边
        const incomingEdges = edges.filter(edge => edge.target === nodeId);
        console.log(`找到 ${incomingEdges.length} 条指向节点 ${nodeId} 的边`);
        
        for (const edge of incomingEdges) {
          const sourceNodeId = edge.source;
          const sourceNode = nodes.find(n => n.id === sourceNodeId);
          // 如果是模型评估节点，输出额外调试信息
          if (nodeToExecute.data.type === 'model_evaluation' && sourceNode) {
            console.log(`模型评估节点的上游节点 ${sourceNodeId}，类型: ${sourceNode.data.type}`);
            console.log(`上游节点 ${sourceNodeId} 的执行结果:`, sourceNode.data.lastExecutionResult);
          }
          
          // 如果上游节点尚未添加到nodesMap，则添加
          if (!nodesMap[sourceNodeId]) {
            if (sourceNode) {
              console.log(`显式添加上游节点 ${sourceNodeId} 数据供节点 ${nodeToExecute.data.type} 使用`);
              nodesMap[sourceNodeId] = {
                id: sourceNodeId,
                data: {
                  ...sourceNode.data,
                  ...(sourceNode.data.lastExecutionResult ? { lastExecutionResult: sourceNode.data.lastExecutionResult } : {}),
                  params: {
                    ...sourceNode.data.params,
                    file: undefined
                  }
                }
              };
              
              // 确保上游节点ID也被添加到nodeIds中
              if (!nodeIds.includes(sourceNodeId)) {
                console.log(`将上游节点 ${sourceNodeId} 添加到执行列表`);
                nodeIds = [sourceNodeId, ...nodeIds];
              }
            }
          }
        }
      }
      
      // 创建请求体 - 修改为数组格式
      const requestBody = {
        node_ids: nodeIds,
        workflow_id: Number(id) || 1, // 确保workflow_id是数字
        nodes: Object.values(nodesMap) // 将对象转换为数组
      };
      
      console.log("发送执行请求:", JSON.stringify(requestBody, null, 2));
      
      const response = await fetch('/api/execute-nodes', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(requestBody),
      });

      console.log("响应状态:", response.status, response.statusText);
      
      // 获取响应文本，无论是否成功
      const responseText = await response.text();
      console.log("原始响应内容:", responseText);
      
      // 尝试解析为JSON
      let responseData;
      try {
        responseData = JSON.parse(responseText);
      } catch (e) {
        console.error("响应不是有效的JSON:", e);
        throw new Error(`服务器返回了非JSON响应: ${responseText}`);
      }
      
      if (!response.ok) {
        console.error("执行失败:", responseData);
        if (responseData.detail) {
          const errorDetail = typeof responseData.detail === 'object' 
            ? JSON.stringify(responseData.detail) 
            : responseData.detail;
          throw new Error(errorDetail || '节点执行失败');
        } else {
          throw new Error('执行失败: ' + (responseData.message || response.statusText));
        }
      }

      console.log("执行结果:", responseData);
      
      // 更新节点的执行结果
      if (responseData.results) {
        setNodes(nds => {
          const updatedNodes = nds.map(n => {
            const result = responseData.results[n.id];
            if (result) {
              console.log(`更新节点 ${n.id} 的执行结果:`, result);
              
              // 特别处理模型评估节点的结果
              if (n.data.type === 'model_evaluation') {
                console.log(`模型评估节点 ${n.id} 执行结果详情:`, result);
                if (result.status === 'error') {
                  console.error(`模型评估节点执行失败:`, result.message);
                } else if (!result.metrics) {
                  console.error(`模型评估节点没有返回metrics数据`);
                } else {
                  console.log(`模型评估节点metrics数据:`, result.metrics);
                }
              }
              
              return {
                ...n,
                data: {
                  ...n.data,
                  lastExecutionResult: result
                }
              };
            }
            return n;
          });
          
          // 如果当前有选中的节点，且它是刚刚被更新的节点之一，则更新selectedNode
          if (selectedNode) {
            const updatedSelectedNode = updatedNodes.find(n => n.id === selectedNode.id);
            if (updatedSelectedNode && responseData.results[selectedNode.id]) {
              console.log("更新选中节点状态:", updatedSelectedNode);
              setTimeout(() => setSelectedNode(updatedSelectedNode), 0);
            }
          }
          
          return updatedNodes;
        });
      }
      
      return responseData;
    } catch (error) {
      console.error("执行异常:", error);
      throw error;
    }
  }, [getPredecessorNodes, nodes, edges, id, selectedNode]);
  
  // 初始化handleNodeExecute函数的ref
  useEffect(() => {
    nodeExecuteRef.current = handleNodeExecute;
  }, [handleNodeExecute]);

  // 监听页面大小变化
  useEffect(() => {
    console.log("全局tablePageSize状态已更新:", tablePageSize);
  }, [tablePageSize]);
  
  // 监听节点变化，更新selectedNode
  useEffect(() => {
    if (selectedNode) {
      const currentNodeInList = nodes.find(n => n.id === selectedNode.id);
      if (currentNodeInList && JSON.stringify(currentNodeInList) !== JSON.stringify(selectedNode)) {
        console.log("在节点列表变化后更新选中节点:", currentNodeInList);
        setSelectedNode(currentNodeInList);
      }
    }
  }, [nodes, selectedNode]);
  
  // 添加事件监听器，监听节点执行按钮点击事件
  useEffect(() => {
    const handleExecuteNodeEvent = (event: CustomEvent) => {
      const { nodeId } = event.detail;
      console.log('接收到节点执行事件:', nodeId);
      if (nodeId) {
        nodeExecuteRef.current(nodeId).catch(err => {
          console.error('执行节点失败:', err);
          let errorMessage = '执行失败';
          if (err instanceof Error) {
            errorMessage = err.message;
          } else if (typeof err === 'object') {
            errorMessage = JSON.stringify(err);
          } else if (err) {
            errorMessage = String(err);
          }
          setError(errorMessage);
        });
      }
    };

    // 添加事件监听器
    window.addEventListener('execute-node', handleExecuteNodeEvent as EventListener);

    // 在组件卸载时移除事件监听器
    return () => {
      window.removeEventListener('execute-node', handleExecuteNodeEvent as EventListener);
    };
  }, []);
  
  // 处理结构化视图节点
  const handleStructuredViewNode = useCallback(async (nodeId: string) => {
    try {
      setIsLoading(true);
      setError(null);
      setSuccess(null);
      
      // 先关闭对话框
      setIsDataTableOpen(false);
      setTableData(null);
      setTableColumns(null);
      
      console.log("开始执行结构化视图节点:", nodeId);
      
      // 查找当前节点
      const currentNode = nodes.find(node => node.id === nodeId);
      if (!currentNode) {
        throw new Error('找不到当前节点');
      }
      
      // 获取当前节点的设置
      const currentPageSize = Number(currentNode.data.params?.page_size) || 10;
      const currentMaxRows = Number(currentNode.data.params?.max_rows) || 100;
      
      console.log("当前节点设置 - 每页行数:", currentPageSize, "最大行数:", currentMaxRows);
      
      // 立即更新页面大小状态
      setTablePageSize(currentPageSize);
      
      // 查找指向结构化视图节点的边
      const incomingEdges = edges.filter(edge => edge.target === nodeId);
      
      if (incomingEdges.length === 0) {
        throw new Error('结构化视图节点需要连接到数据源节点');
      }
      
      // 获取上游节点的ID
      const sourceNodeId = incomingEdges[0].source;
      const sourceNode = nodes.find(node => node.id === sourceNodeId);
      
      if (!sourceNode) {
        throw new Error('找不到数据源节点');
      }
      
      // 设置表格标题
      const sourceNodeName = sourceNode.data.label || '数据';
      setTableTitle(`${sourceNodeName} 预览`);
      
      // 执行上游节点以获取数据
      console.log("开始执行上游节点:", sourceNodeId);
      const result = await nodeExecuteRef.current(sourceNodeId);
      
      if (!result || !result.results || !result.results[sourceNodeId]) {
        throw new Error('无法获取数据源数据');
      }
      
      const nodeResult = result.results[sourceNodeId];
      
      if (nodeResult.status !== 'success' || !nodeResult.data) {
        throw new Error(nodeResult.message || '数据获取失败');
      }
      
      // 设置表格数据和列
      const data = nodeResult.data;
      const columns = nodeResult.columns || Object.keys(data[0] || {});
      const rowCount = nodeResult.row_count || data.length;
      
      console.log(`数据获取成功: ${rowCount} 行, ${columns.length} 列, 将使用每页行数: ${currentPageSize}`);
      
      console.log(`数据大小: ${data.length}`);
      
      // 更新结构化视图节点参数，存储行数和列信息
      setNodes(nds => 
        nds.map(n => {
          if (n.id === nodeId) {
            // 保留用户设置的参数，添加数据源信息
            const updatedParams = {
              ...(n.data.params || {}),
              row_count: rowCount,
              column_count: columns.length,
              source_node: sourceNodeName,
              source_node_id: sourceNodeId,
              // 确保这些参数被保留
              page_size: currentPageSize,
              max_rows: currentMaxRows
            };
            
            return {
              ...n,
              data: {
                ...n.data,
                params: updatedParams
              }
            };
          }
          return n;
        })
      );
      
      // 所有状态更新完成后，设置表格数据并打开对话框
      // 使用更长的延迟以确保所有状态已更新
      setTimeout(() => {
        // 最后设置表格数据，避免在对话框打开前就处理数据
        setTableData(data);
        setTableColumns(columns);
        
        // 设置成功状态并打开对话框
        setSuccess('数据加载成功');
        console.log("准备打开表格对话框 - 当前页面大小:", currentPageSize, "表格行数:", data.length);
        setIsDataTableOpen(true);
        setIsLoading(false);
      }, 500);
      
    } catch (err) {
      console.error("结构化视图执行失败:", err);
      setError(err instanceof Error ? err.message : '执行失败');
      setIsLoading(false);
    }
  }, [edges, nodes, setNodes]);

  // 加载工作流数据
  useEffect(() => {
    const loadWorkflow = async () => {
      if (id === 'new') {
        setIsNewWorkflow(true)
        setWorkflowName('新工作流')
        setWorkflowDescription('')
        setNodes([])
        setEdges([])
        return
      }

      try {
        const response = await workflows.get(Number(id))
        const workflow = response.data
        setWorkflowName(workflow.name)
        setWorkflowDescription(workflow.description || '')
        setNodes(workflow.nodes || [])
        setEdges(workflow.edges || [])
      } catch (error) {
        console.error('加载工作流失败:', error)
        setError('加载工作流失败')
      }
    }

    loadWorkflow()
  }, [id])

  // 保存工作流
  const handleSave = async () => {
    try {
      setIsLoading(true)
      
      // 确保所有边的信息正确
      const edgesWithSourceTarget = edges.map(edge => ({
        ...edge,
        source: String(edge.source),
        target: String(edge.target)
      }));
      
      console.log("保存边连接信息:", edgesWithSourceTarget);
      
      const workflowData = {
        name: workflowName,
        description: workflowDescription,
        nodes,
        edges: edgesWithSourceTarget,
        user_id: 1, // 临时使用固定用户ID，后续需要从登录用户信息中获取
      }

      if (isNewWorkflow) {
        const response = await workflows.create(workflowData)
        // 如果是新工作流，保存后将 id 更新为新创建的 id，并将状态设置为非新工作流
        if (response && response.data && response.data.id) {
          navigate(`/workflow/${response.data.id}`, { replace: true })
          setIsNewWorkflow(false)
        }
        setSuccess('工作流创建成功')
      } else {
        await workflows.update(Number(id), workflowData)
        setSuccess('工作流更新成功')
      }
      
      // 移除自动跳转
      // setTimeout(() => {
      //   navigate('/workflows')
      // }, 1500)
    } catch (error) {
      console.error('保存工作流失败:', error)
      setError('保存工作流失败')
    } finally {
      setIsLoading(false)
    }
  }

  // 处理节点点击
  const handleNodeClick = useCallback((event: React.MouseEvent, node: CustomNode) => {
    event.stopPropagation() // 阻止事件冒泡
    setSelectedNode(node)
    setSelectedEdge(null)
    setIsDrawerOpen(true)
  }, [])

  // 处理画布点击
  const handlePaneClick = useCallback(() => {
    setSelectedNode(null)
    setSelectedEdge(null)
    setIsDrawerOpen(false)
  }, [])

  // 处理边点击
  const handleEdgeClick = useCallback((event: React.MouseEvent, edge: Edge) => {
    setSelectedEdge(edge)
    setSelectedNode(null)
    setIsDrawerOpen(true)
  }, [])

  // 处理连接
  const onConnect = useCallback(
    (params: Connection) => {
      setEdges((eds) => {
        // 添加边的同时设置箭头标记，以显示方向
        const newEdge = {
          ...params,
          markerEnd: {
            type: MarkerType.ArrowClosed,
            width: 20,
            height: 20
          },
          style: { stroke: '#555' },
        };
        return addEdge(newEdge, eds);
      });
    },
    [setEdges]
  )

  // 处理节点拖拽
  const handleNodeDragStop = useCallback(
    (event: React.MouseEvent, node: CustomNode) => {
      setNodes((nds) =>
        nds.map((n) => {
          if (n.id === node.id) {
            return {
              ...n,
              position: node.position,
            }
          }
          return n
        })
      )
    },
    [setNodes]
  )

  // 处理节点删除
  const handleNodeDelete = useCallback(
    (nodeId: string) => {
      console.log("删除节点:", nodeId);
      
      // 如果要删除的是当前选中的节点，清除选中状态并关闭面板
      if (selectedNode && selectedNode.id === nodeId) {
        setSelectedNode(null);
        setIsDrawerOpen(false);
      }
      
      // 从节点列表中移除该节点
      setNodes((nds) => nds.filter((n) => n.id !== nodeId));
      
      // 移除与该节点相关的所有边
      setEdges((eds) =>
        eds.filter(
          (e) => e.source !== nodeId && e.target !== nodeId
        )
      );
    },
    [setNodes, setEdges, selectedNode]
  )

  // 先定义 handleEdgeDelete 函数
  const handleEdgeDelete = useCallback(
    (edgeId: string) => {
      setEdges((eds) => eds.filter((e) => e.id !== edgeId))
    },
    [setEdges]
  );

  // 然后定义使用 handleEdgeDelete 的 useEffect
  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === 'Delete') {
        // 如果有选中的节点
        if (selectedNode) {
          console.log("按Delete键删除节点:", selectedNode.id);
          if (window.confirm('确定要删除此节点吗？')) {
            handleNodeDelete(selectedNode.id);
          }
        } 
        // 如果有选中的边
        else if (selectedEdge) {
          console.log("按Delete键删除边:", selectedEdge.id);
          if (window.confirm('确定要删除此连接吗？')) {
            handleEdgeDelete(selectedEdge.id);
            // 删除边后，清除选中状态并关闭面板
            setSelectedEdge(null);
            setIsDrawerOpen(false);
          }
        }
      }
    };
    
    window.addEventListener('keydown', handleKeyDown);
    
    return () => {
      window.removeEventListener('keydown', handleKeyDown);
    };
  }, [selectedNode, selectedEdge, handleNodeDelete, handleEdgeDelete, setSelectedEdge, setIsDrawerOpen]);

  // 处理节点参数更新
  const handleNodeParamsUpdate = useCallback(
    (nodeId: string, data: any) => {
      console.log('更新节点数据:', nodeId, data);
      setNodes((nds) => {
        // 先创建更新后的节点数组
        const updatedNodes = nds.map((n) => {
          if (n.id === nodeId) {
            // 创建更新后的节点数据
            const updatedNodeData = { ...n.data };
            
            // 如果有params字段，更新params
            if (data.params) {
              updatedNodeData.params = {
                ...(updatedNodeData.params || {}),
                ...data.params
              };
            }
            
            // 如果有label字段，更新label
            if (data.label !== undefined) {
              updatedNodeData.label = data.label;
            }
            
            // 返回更新后的节点
            return {
              ...n,
              data: updatedNodeData
            };
          }
          return n;
        });
        
        // 如果当前选中的节点就是被更新的节点，也更新selectedNode
        if (selectedNode && selectedNode.id === nodeId) {
          const updatedSelectedNode = updatedNodes.find(n => n.id === nodeId);
          if (updatedSelectedNode) {
            console.log("更新选中节点状态:", updatedSelectedNode);
            setTimeout(() => setSelectedNode(updatedSelectedNode), 0);
          }
        }
        
        return updatedNodes;
      });
    },
    [setNodes, selectedNode]
  )

  // 处理预览
  const handlePreview = useCallback(() => {
    setIsPreviewOpen(true)
  }, [])

  // 处理执行
  const handleExecute = useCallback(() => {
    setIsExecuteDialogOpen(true)
  }, [])

  // 处理执行确认
  const handleExecuteConfirm = async () => {
    try {
      setIsLoading(true)
      await workflows.execute(Number(id))
      setSuccess('工作流执行成功')
      setIsExecuteDialogOpen(false)
    } catch (error) {
      console.error('执行工作流失败:', error)
      setError('执行工作流失败')
    } finally {
      setIsLoading(false)
    }
  }

  // 处理取消
  const handleCancel = () => {
    navigate('/workflows')
  }

  // 处理错误关闭
  const handleErrorClose = () => {
    setError(null)
  }

  // 处理成功关闭
  const handleSuccessClose = () => {
    setSuccess(null)
  }

  // 处理拖放
  const onDrop = useCallback(
    (event: React.DragEvent) => {
      event.preventDefault()

      const type = event.dataTransfer.getData('application/reactflow')
      const label = event.dataTransfer.getData('label')

      // 检查是否是有效的节点类型
      if (typeof type === 'undefined' || !type) {
        return
      }

      // 获取拖放位置并转换为画布坐标
      const position = reactFlowInstance.screenToFlowPosition({
        x: event.clientX,
        y: event.clientY,
      })

      // 创建新节点
      const newNode: CustomNode = {
        id: `${type}-${Date.now()}`,
        type: 'custom',
        position,
        data: {
          label,
          type,
        },
      }

      setNodes((nds) => nds.concat(newNode))
    },
    [setNodes, reactFlowInstance]
  )

  // 处理拖拽悬停
  const onDragOver = useCallback((event: React.DragEvent) => {
    event.preventDefault()
    event.dataTransfer.dropEffect = 'move'
  }, [])

  // 添加页面大小修改处理函数
  const handleTablePageSizeChange = useCallback((newSize: number) => {
    console.log("更新表格每页行数:", newSize);
    
    // 首先更新全局状态
    setTablePageSize(newSize);
    
    // 如果有选中的节点，更新节点参数
    if (selectedNode && selectedNode.data.type === 'structured_view') {
      // 更新节点参数
      setNodes(nds => 
        nds.map(n => {
          if (n.id === selectedNode.id) {
            return {
              ...n,
              data: {
                ...n.data,
                params: {
                  ...(n.data.params || {}),
                  page_size: newSize
                }
              }
            };
          }
          return n;
        })
      );
    }
  }, [selectedNode, setNodes]);

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
      {/* 顶部工具栏 */}
      <Box
        sx={{
          p: 1,
          px: 2,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-between',
          backgroundColor: '#fff',
          borderBottom: '1px solid #eaeaea',
          boxShadow: '0 2px 10px rgba(0,0,0,0.05)',
          zIndex: 100,
        }}
      >
        <Box sx={{ display: 'flex', alignItems: 'center' }}>
          <IconButton onClick={handleCancel} size="small" sx={{ mr: 1 }}>
            <ArrowBackIcon />
          </IconButton>
          
          <TextField
            variant="standard"
            placeholder="输入工作流名称"
            value={workflowName}
            onChange={(e) => setWorkflowName(e.target.value)}
            InputProps={{
              disableUnderline: true,
              sx: { 
                fontSize: '1.2rem', 
                fontWeight: 600,
                '&:hover, &:focus': {
                  backgroundColor: '#f5f5f5',
                  borderRadius: '4px',
                  px: 1,
                }
              }
            }}
            sx={{ 
              minWidth: 200,
              mr: 2,
            }}
          />
          
          <TextField
            variant="standard"
            placeholder="添加描述..."
            value={workflowDescription}
            onChange={(e) => setWorkflowDescription(e.target.value)}
            InputProps={{
              disableUnderline: true,
              sx: { 
                fontSize: '0.9rem',
                color: 'text.secondary',
                '&:hover, &:focus': {
                  backgroundColor: '#f5f5f5',
                  borderRadius: '4px',
                  px: 1,
                }
              }
            }}
            sx={{ minWidth: 300 }}
          />
        </Box>

        <Box>
          <Button
            variant="outlined"
            size="small"
            onClick={() => setIsPreviewOpen(true)}
            startIcon={<VisibilityIcon />}
            sx={{ mr: 1, borderRadius: '20px' }}
          >
            预览
          </Button>
          
          <Button
            variant="outlined"
            size="small"
            onClick={() => setIsExecuteDialogOpen(true)}
            startIcon={<PlayArrowIcon />}
            sx={{ mr: 1, borderRadius: '20px' }}
          >
            执行
          </Button>
          
          <Button
            variant="contained"
            color="primary"
            size="small"
            onClick={handleSave}
            startIcon={<SaveIcon />}
            disabled={isLoading}
            sx={{ borderRadius: '20px' }}
          >
            {isLoading ? <CircularProgress size={20} /> : '保存'}
          </Button>
        </Box>
      </Box>

      <Box sx={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
        <NodePanel />
        <Box
          sx={{ 
            flex: 1, 
            position: 'relative',
            display: 'flex',
            flexDirection: 'column',
            height: '100%',
            overflow: 'hidden',
          }}
        >
          <Box
            sx={{ 
              flex: 1,
              position: 'relative',
              backgroundColor: '#fafafa',
              backgroundImage: 'radial-gradient(#e0e0e0 1px, transparent 1px)',
              backgroundSize: '20px 20px',
            }}
            onDrop={onDrop}
            onDragOver={onDragOver}
          >
            <ReactFlow
              nodes={nodes}
              edges={edges}
              onNodesChange={onNodesChange}
              onEdgesChange={onEdgesChange}
              onConnect={onConnect}
              onNodeClick={handleNodeClick}
              onEdgeClick={handleEdgeClick}
              onNodeDragStop={handleNodeDragStop}
              onPaneClick={handlePaneClick}
              nodeTypes={nodeTypeMapping}
              fitView
              minZoom={0.2}
              maxZoom={2}
              zoomOnScroll={true}
              zoomOnPinch={true}
              panOnScroll={true}
              panOnDrag={true}
              snapToGrid={true}
              snapGrid={[20, 20]}
            >
              <Background size={1} gap={20} />
              <Controls
                position="bottom-left"
                style={{
                  display: 'flex',
                  flexDirection: 'column',
                  padding: '8px',
                  backgroundColor: 'white',
                  borderRadius: '8px',
                  boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
                }}
              />
              <MiniMap
                nodeStrokeWidth={3}
                nodeColor={(node) => {
                  // 添加类型安全检查
                  if (!node.data || typeof node.data.type !== 'string') {
                    return '#607d8b'; // 默认颜色
                  }
                  
                  const nodeCategory = node.data.type.split('_')[0];
                  switch(nodeCategory) {
                    case 'data': return '#4caf50';
                    case 'csv': 
                    case 'excel': 
                    case 'db': return '#2196f3';
                    case 'random': 
                    case 'logistic': 
                    case 'svm': return '#9c27b0';
                    case 'structured': return '#ff9800';
                    default: return '#607d8b';
                  }
                }}
                style={{
                  height: 120,
                  width: 200,
                  right: 10,
                  bottom: 10,
                  backgroundColor: 'white',
                  borderRadius: '8px',
                  boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
                }}
              />
            </ReactFlow>
          </Box>
        </Box>

        <Drawer
          anchor="right"
          open={isDrawerOpen}
          onClose={() => setIsDrawerOpen(false)}
          variant="persistent"
          sx={{
            '& .MuiDrawer-paper': {
              width: 320,
              height: '100%',
              boxSizing: 'border-box',
              position: 'relative',
              boxShadow: '-4px 0 10px rgba(0,0,0,0.05)',
              borderLeft: '1px solid #eaeaea',
            },
          }}
        >
          <Box sx={{ 
            width: '100%', 
            p: 3,
            height: '100%',
            overflow: 'auto'
          }}>
            {selectedNode && (
              <PropertiesPanel
                node={selectedNode}
                onUpdate={handleNodeParamsUpdate}
                onDelete={handleNodeDelete}
                onExecute={handleNodeExecute}
                getUpstreamData={getUpstreamData}
              />
            )}
            {selectedEdge && (
              <EdgePropertiesPanel
                edge={selectedEdge}
                onDelete={handleEdgeDelete}
              />
            )}
          </Box>
        </Drawer>
      </Box>

      {/* 预览对话框 */}
      <Dialog
        open={isPreviewOpen}
        onClose={() => setIsPreviewOpen(false)}
        maxWidth="md"
        fullWidth
        PaperProps={{
          sx: {
            borderRadius: '12px',
            overflow: 'hidden',
          }
        }}
      >
        <DialogTitle sx={{ 
          backgroundColor: '#f5f5f5', 
          fontWeight: 600,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center'
        }}>
          工作流预览
          <IconButton onClick={() => setIsPreviewOpen(false)} size="small">
            <DeleteIcon />
          </IconButton>
        </DialogTitle>
        <DialogContent>
          <PreviewPanel nodes={nodes} edges={edges} />
        </DialogContent>
      </Dialog>

      {/* 执行对话框 */}
      <Dialog
        open={isExecuteDialogOpen}
        onClose={() => setIsExecuteDialogOpen(false)}
        maxWidth="sm"
        fullWidth
        PaperProps={{
          sx: {
            borderRadius: '12px',
            overflow: 'hidden',
          }
        }}
      >
        <DialogTitle sx={{ backgroundColor: '#f5f5f5', fontWeight: 600 }}>
          执行工作流
        </DialogTitle>
        <DialogContent>
          <Box sx={{ py: 2 }}>
            <Typography paragraph>
              确定要执行当前工作流吗？这将运行所有节点的计算任务。
            </Typography>
          </Box>
        </DialogContent>
        <DialogActions sx={{ p: 2, pt: 0 }}>
          <Button
            onClick={() => setIsExecuteDialogOpen(false)}
            color="inherit"
            variant="outlined"
            size="small"
            sx={{ borderRadius: '20px' }}
          >
            取消
          </Button>
          <Button
            onClick={handleExecuteConfirm}
            color="primary"
            variant="contained"
            size="small"
            sx={{ borderRadius: '20px' }}
          >
            执行
          </Button>
        </DialogActions>
      </Dialog>

      {/* 结构化视图对话框 */}
      <DataTableDialog
        open={isDataTableOpen}
        onClose={() => setIsDataTableOpen(false)}
        data={tableData}
        columns={tableColumns}
        title={tableTitle}
        pageSize={tablePageSize}
        onPageSizeChange={(newPageSize) => {
          setTablePageSize(newPageSize);
          if (selectedNode && selectedNode.data.type === 'structured_view') {
            handleNodeParamsUpdate(selectedNode.id, { page_size: newPageSize });
          }
        }}
      />

      {/* 错误提示 */}
      <Snackbar
        open={!!error}
        autoHideDuration={5000}
        onClose={handleErrorClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
      >
        <Alert onClose={handleErrorClose} severity="error" variant="filled">
          {error}
        </Alert>
      </Snackbar>

      {/* 成功提示 */}
      <Snackbar
        open={!!success}
        autoHideDuration={3000}
        onClose={handleSuccessClose}
        anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
      >
        <Alert onClose={handleSuccessClose} severity="success" variant="filled">
          {success}
        </Alert>
      </Snackbar>
    </Box>
  )
}

// 创建一个包装组件
const WorkflowEditorWrapper = () => {
  return (
    <ReactFlowProvider>
      <WorkflowEditor />
    </ReactFlowProvider>
  )
}

export default WorkflowEditorWrapper 